package com.ygqh.baby.service.wdtqyb.builder;

import com.ygqh.baby.ao.OrderDetailStatus;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.RefundStatus;
import com.ygqh.baby.model.wdt.qyb.PushOrderToWdtResult;
import com.ygqh.baby.model.wdt.qyb.WdtQybOrderLstReq;
import com.ygqh.baby.model.wdt.qyb.WdtQybOrderReq;
import com.ygqh.baby.po.YgOrder;
import com.ygqh.baby.po.YgOrderDetail;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class WdtOrderBuiler {

    private YgOrder order;

    private List<YgOrderDetail> detailList;

    private String tid;


    private WdtOrderBuiler() {
    }

    public WdtOrderBuiler(YgOrder order, List<YgOrderDetail> detailList, String tid) {
        this.order = order;
        this.detailList = detailList;
        this.tid = tid;
    }

//    public WdtOrderBuiler(YgOrder order, List<YgOrderDetail> detailList, int pushTimes) {
//        this.order = order;
//        this.detailList = detailList;
//        this.tid = getOrderCodeToWdt(pushTimes, order.getOrderId());
//    }

    public WdtQybOrderReq builder() {
        resetOrderInfoBySalePrice(order, detailList);
        WdtQybOrderReq wdtQybOrderReq = buildWdtOrder(order);
        List<WdtQybOrderLstReq> lstReqs = buildWdtOrderDetail(detailList);
        wdtQybOrderReq.setOrderList(lstReqs);
        wdtQybOrderReq.setTid(tid);
        return wdtQybOrderReq;

    }

    public PushOrderToWdtResult buildPushResult() {
        PushOrderToWdtResult pushOrderToWdtResult = new PushOrderToWdtResult();
        pushOrderToWdtResult.setOrderCode(order.getOrderId().toString());
        pushOrderToWdtResult.setDetailIdList(detailList.stream().filter(od -> !"FortuneBagDetail".equals(od.getPromotionRemark()))
                .map(YgOrderDetail::getId).collect(Collectors.toList()));
        pushOrderToWdtResult.setMsg("ok");
        pushOrderToWdtResult.setTid(tid);
        return pushOrderToWdtResult;
    }

    private WdtQybOrderReq buildWdtOrder(YgOrder order) {
        // 订单主信息
        WdtQybOrderReq orderReq = new WdtQybOrderReq();
        orderReq.setTradeStatus(getWdtOrderStatus(order.getOrderStatus()));
        //1:款到发货,2:货到付款(包含部分货到付款),3:分期付款
        orderReq.setDeliveryTerm(1);
        orderReq.setPayStatus(getWdtPayStatus(order));

        orderReq.setBuyerNick(getBuyerNick(order.getUserName()));
        orderReq.setBuyerMessage(order.getUserRemark());
        orderReq.setTradeTime(order.getCreateTime());
        orderReq.setPayTime(order.getPaidTime());
//        orderReq.setSellerMemo(order.getPlatformName());

        orderReq.setReceiverName(order.getReceiver());
        orderReq.setReceiverProvince(order.getProvinceName());
        orderReq.setReceiverCity(order.getCityName());
        orderReq.setReceiverDistrict(order.getAreaName());
        orderReq.setReceiverAddress(order.getAddress());
        orderReq.setReceiverMobile(order.getTelPhone());
        orderReq.setReceiverTelno(order.getTelPhone());
        orderReq.setLogisticsType("-1");
        orderReq.setPostAmount(BigDecimal.ZERO.toString());
        orderReq.setCodAmount(BigDecimal.ZERO.toString());
        orderReq.setExtCodFee(BigDecimal.ZERO.toString());
        orderReq.setOtherAmount(BigDecimal.ZERO.toString());
        orderReq.setOtherAmount(BigDecimal.ZERO.toString());
        orderReq.setPaid(order.getPaidPrice().toString());
        return orderReq;
    }

    private String getBuyerNick(String userName) {
        if (userName.length() > 12) {
            userName = userName.substring(0, 11);
        }
        return userName;
    }

    private static final String ORDER_CODE_TEMPLATE = "S%sW%s";

    /**
     * 获取按明细推送的单号
     *
     * @param pushWdtTimes 推送次数
     * @param orderId      原订单号
     * @return String
     */
    public static String getOrderCodeToWdt(int pushWdtTimes, Long orderId) {
        return String.format(ORDER_CODE_TEMPLATE, (pushWdtTimes + 1), orderId);
    }


    /**
     * 根据明细设置订单金额信息
     *
     * @param order           原订单
     * @param waitingPushList 待推送明细
     */
    private void resetOrderInfoBySalePrice(YgOrder order, List<YgOrderDetail> waitingPushList) {
        BigDecimal totalPrice = waitingPushList.stream().filter(od -> !RefundStatus.RefundSuccess.equals(od.getRefundStatus()))
                .map(od -> od.getSalePrice().multiply(new BigDecimal(od.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        order.setTotalPrice(totalPrice);
        order.setPaidPrice(totalPrice);
        order.setAccountPrice(BigDecimal.ZERO);
        OrderStatus orderStatusByDetail = getOrderStatusByDetail(order.getOrderStatus(), waitingPushList);
        order.setOrderStatus(orderStatusByDetail);

    }

    /**
     * 根据明细设置订单金额信息
     *
     * @param order           原订单
     * @param waitingPushList 待推送明细
     * @return boolean 返回是否为零元订单
     */
    private boolean resetOrderInfoByDetail(YgOrder order, List<YgOrderDetail> waitingPushList) {
        boolean zeroOrder = false;
        if (BigDecimal.ZERO.compareTo(order.getTotalPrice()) == 0) {
            zeroOrder = true;
            BigDecimal totalPrice = waitingPushList.stream().map(YgOrderDetail::getSalePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            order.setTotalPrice(BigDecimal.ZERO);
            order.setAccountPrice(totalPrice);
            order.setPaidPrice(BigDecimal.ZERO);

        } else {
            BigDecimal totalPrice = waitingPushList.stream().map(YgOrderDetail::getRealPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            order.setTotalPrice(totalPrice);
            order.setPaidPrice(totalPrice);
            order.setAccountPrice(BigDecimal.ZERO);
        }
        OrderStatus orderStatusByDetail = getOrderStatusByDetail(order.getOrderStatus(), waitingPushList);
        order.setOrderStatus(orderStatusByDetail);
        return zeroOrder;

    }

    private OrderStatus getOrderStatusByDetail(OrderStatus sourceOrderStatus, List<YgOrderDetail> waitingPushList) {
        if (OrderStatus.WaitingPay.equals(sourceOrderStatus) || OrderStatus.TradeClosed.equals(sourceOrderStatus)) {
            return sourceOrderStatus;
        }
        long count = waitingPushList.stream().filter(ygOrderDetail -> RefundStatus.RefundSuccess.equals(ygOrderDetail.getRefundStatus())).count();
        if (count < waitingPushList.size()) {
            OrderDetailStatus detailStatus = waitingPushList.get(0).getDetailStatus();
            if (OrderDetailStatus.WaitingSign.equals(detailStatus)) {
                return OrderStatus.WaitingSign;
            }
            return OrderStatus.WaitingSend;

        } else {
            return OrderStatus.TradeClosed;
        }
    }

    /**
     * 获取旺店通订单支付状态值
     *
     * @param order 壹果订单
     */
    private String getWdtPayStatus(YgOrder order) {
        String payStatus = "0";
        if (order.getPaidTime() != null) {
            payStatus = "2";
        }
        return payStatus;
    }

    /**
     * 构建旺店通订单明细
     * <p>
     * 价格不平
     *
     * @param orderDetailList 订单明细集合
     * @return List<WdtQybOrderLstReq>
     */
    @Deprecated
    private List<WdtQybOrderLstReq> buildWdtOrderDetail(List<YgOrderDetail> orderDetailList, Boolean zeroOrder) {

        List<WdtQybOrderLstReq> lstReqs = new ArrayList<>(orderDetailList.size());
        for (YgOrderDetail od : orderDetailList) {
            String oid = od.getOrderId() + "-" + od.getId();
            WdtQybOrderLstReq wdtQybOrderLstReq = new WdtQybOrderLstReq();
            wdtQybOrderLstReq.setOid(oid);
            wdtQybOrderLstReq.setStatus(1);
            wdtQybOrderLstReq.setNum(new BigDecimal(od.getQuantity()));
            wdtQybOrderLstReq.setPrice(zeroOrder ? od.getSalePrice() : od.getRealPrice());

            wdtQybOrderLstReq.setStatus(getWdtOrderDetailStatus(od.getDetailStatus(), od.getRefundStatus()));
            wdtQybOrderLstReq.setRefundStatus(getWdtOrderDetailRefundStatus(od.getRefundStatus()));

            wdtQybOrderLstReq.setGoodsId(od.getProductCode());
            wdtQybOrderLstReq.setSpecId(od.getSkuCode());
            wdtQybOrderLstReq.setGoodsNo(od.getProductCode());
            wdtQybOrderLstReq.setGoodsName(od.getProductName());
            wdtQybOrderLstReq.setSpecNo(od.getSkuCode());
            wdtQybOrderLstReq.setSpecName(od.getShortName() + " " + od.getSize());
            wdtQybOrderLstReq.setAdjustAmount(BigDecimal.ZERO);
            wdtQybOrderLstReq.setDiscount(zeroOrder ? od.getSalePrice().multiply(new BigDecimal(od.getQuantity())) : BigDecimal.ZERO);

            lstReqs.add(wdtQybOrderLstReq);
        }
        return lstReqs;
    }

    private List<WdtQybOrderLstReq> buildWdtOrderDetail(List<YgOrderDetail> orderDetailList) {

        List<WdtQybOrderLstReq> lstReqs = new ArrayList<>(orderDetailList.size());
        for (YgOrderDetail od : orderDetailList) {
            String oid = tid + "-" + od.getId();
            WdtQybOrderLstReq wdtQybOrderLstReq = new WdtQybOrderLstReq();
            wdtQybOrderLstReq.setOid(oid);
            wdtQybOrderLstReq.setStatus(1);
            wdtQybOrderLstReq.setNum(new BigDecimal(od.getQuantity()));
            wdtQybOrderLstReq.setPrice(od.getSalePrice());

            wdtQybOrderLstReq.setStatus(getWdtOrderDetailStatus(od.getDetailStatus(), od.getRefundStatus()));
            wdtQybOrderLstReq.setRefundStatus(getWdtOrderDetailRefundStatus(od.getRefundStatus()));

            wdtQybOrderLstReq.setGoodsId(od.getProductCode());
            wdtQybOrderLstReq.setSpecId(od.getSkuCode());
            wdtQybOrderLstReq.setGoodsNo(od.getProductCode());
            wdtQybOrderLstReq.setGoodsName(od.getProductName());
            wdtQybOrderLstReq.setSpecNo(od.getSkuCode());
            wdtQybOrderLstReq.setSpecName(od.getShortName() + " " + od.getSize());
            wdtQybOrderLstReq.setAdjustAmount(BigDecimal.ZERO);
            wdtQybOrderLstReq.setDiscount(BigDecimal.ZERO);

            lstReqs.add(wdtQybOrderLstReq);
        }
        return lstReqs;
    }


    private int getWdtOrderDetailStatus(OrderDetailStatus detailStatus, RefundStatus refundStatus) {
        if (RefundStatus.RefundSuccess.equals(refundStatus)) {
            return 80;
        }
        int status;
        switch (detailStatus) {
            case WaitingSend:
                status = 30;
                break;
            case WaitingSign:
                status = 50;
                break;
            case Audited:
                status = 55;
                break;
            default:
                status = 30;
        }
        return status;
    }

    private int getWdtOrderDetailRefundStatus(RefundStatus refundStatus) {
        int status;
        switch (refundStatus) {
            case NoRefund:
                status = 0;
                break;
            case ApplyRefund:
                status = 2;
                break;
            case RefundSuccess:
                status = 5;
                break;
            default:
                status = 0;
        }
        return status;
    }

    /**
     * 获取旺店通订单状态
     * <p>
     * trade_status=10  未确认，客户只拍单未未付款(等待付款的订单,货到付款（COD）订单不需要等付款，直接进行待发货)
     * trade_status=20	待尾款(预付定金订单,等尾款付完后进入发货流程)
     * trade_status=30	已付款待发货(包含货到付款)，30只可以直接变更为70/ 80这2种状态
     * trade_status=40	部分发货(拆分发货才会出现)
     * trade_status=50	已发货(平台上订单状态已经发货)
     * trade_status=70	已完成（已签收），平台订单完成（客户确认收货）后，推送此状态;
     * 订单为自动流转模式时，初次推送的平台订单状态直接就是已完成状态70
     * trade_status=80	已退款(付过款后来全部退款了)
     * trade_status=90
     * <p>
     * 已关闭(未付款直接取消的订单)
     *
     * @param orderStatus 壹果订单状态
     * @return int
     */
    private int getWdtOrderStatus(OrderStatus orderStatus) {
        int status;
        switch (orderStatus) {
            case TradeClosed:
                status = 90;
                break;
            case WaitingPay:
                status = 20;
                break;
            case WaitingCheck:
                status = 10;
                break;
            case WaitingSend:
                status = 30;
                break;
            case WaitingSign:
                status = 50;
                break;
            case TradeSuccess:
                status = 70;
                break;
            default:
                status = 10;
        }
        return status;

    }

    public static String getOrderIdFromTid(String tid) {
        if (tid.startsWith("S")) {
            int w = tid.indexOf("W");
            if (w > 0) {
                return tid.substring(w + 1);
            }
            int start = tid.length() - 12;
            return start > 0 ? tid.substring(start) : tid;
        }
        return tid;
    }

}
